package generator

import (
	"fmt"
	"os"
	"text/template"
)

type CodeGenerator struct {
	generators []*Generator
}

func (receiver *CodeGenerator) Generate() {
	for _, g := range receiver.generators {
		g.Generate()
	}
}

func NewCodeGenerator(param Parameter) (*CodeGenerator, error) {
	var codeGenerators = new(CodeGenerator)
	for _, tierParam := range param {
		var g = new(Generator)

		// 若目标文件夹不存在则创建
		if _, err := os.Stat(tierParam.OutputPathPrefix); os.IsNotExist(err) {
			err := os.Mkdir(tierParam.OutputPathPrefix, os.ModePerm)
			if err != nil {
				panic(err)
			}
		}

		g.OutputPathPrefix = tierParam.OutputPathPrefix
		g.ContentParameters = tierParam.Contents

		tmpl := template.New(tierParam.TemplateName + ".tmpl").Funcs(template.FuncMap{"capitalize": CapitalizeFirstLetter})
		tmpl, err := tmpl.ParseFiles(tierParam.TemplatePath)
		if err != nil {
			fmt.Printf("Error parsing template | templatePath: %s | err: %s\n", tierParam.TemplatePath, err)
			return nil, err
		} else {
			g.Template = tmpl
		}

		codeGenerators.generators = append(codeGenerators.generators, g)
	}
	return codeGenerators, nil
}

type Generator struct {
	Template         *template.Template // 模板
	OutputPathPrefix string             // 输出路径前缀

	ContentParameters []ContentParameter
}

func (receiver *Generator) Generate() {
	for _, contentParameter := range receiver.ContentParameters {
		receiver.generate(contentParameter)
	}
}

func (receiver *Generator) generate(contentParam ContentParameter) {
	outputFilePath := fmt.Sprintf("%s/%s.go", receiver.OutputPathPrefix, contentParam.Subject)

	// 创建文件
	file, err := os.Create(outputFilePath)
	if err != nil {
		panic(err)
	}
	defer file.Close()

	// 渲染模板
	err = receiver.Template.Execute(file, contentParam)
	if err != nil {
		fmt.Printf("Error writing to file: %s | err: %s\n", outputFilePath, err)
	} else {
		fmt.Printf("Success writing to file: %s\n", outputFilePath)
	}
}
